package com.wl.dzt.basic.user;

import com.wl.dzt.basic.ApplicationContext;
import com.wl.dzt.basic.entity.*;
import com.wl.dzt.sys.core.dao.DB;
import com.wl.dzt.sys.core.dao.select.Select;
import com.wl.dzt.sys.core.dao.select.term.Term;
import com.wl.dzt.sys.util.CollectionUtil;
import com.wl.dzt.sys.util.LogicUtil;
import com.wl.dzt.sys.util.clazz.ClassUtil;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author wl_code@163.com
 * @version 1.0
 * @date 2018/7/5/005
 * @description 默认登录对象构建器
 */
@Component
public class DefaultUserBuilder implements UserBuilder<BasicUser> {

    @Override
    public User builder(BasicUser systemUser) {
        User user = new User();
        user.setSystemUser(systemUser);
        boolean isAdmin = "admin".equalsIgnoreCase(systemUser.getId());
        {
            // 获取用户基础信息
            user.addAttr("userId", systemUser.getId());
            user.addAttr("uname", systemUser.getUname());
            user.addAttr("name", systemUser.getName());
            user.addAttr("isAdmin", false);
            // 不是超级管理员
            if (!isAdmin) {
                // 获取所属组织机构
                user.addAttr("organId", systemUser.getOrganId().getId());
                user.addAttr("organName", systemUser.getOrganId().getOrganName());

                // 获取所属岗位
                user.addAttr("positionId", systemUser.getPositionId().getId());
                user.addAttr("positionName", systemUser.getPositionId().getPositionName());

                // 获取所属企业域
                user.addAttr("areaId", systemUser.getAreaId().getId());
                user.addAttr("areaName", systemUser.getAreaId().getOrganName());

                // 获取兼职部门以及岗位
                List<BasicPartTime> bpts = DB.list(Select.create(BasicPartTime.class).fields("positionId.id", "organId.id")
                        .where(Term.eq("userId.id", systemUser.getId())));
                List<String> ptIds = new ArrayList<>(), ptNames = new ArrayList<>(), ogIds = new ArrayList<>(), ogNames = new ArrayList<>();
                bpts.forEach(bpt -> {
                    ptIds.add(bpt.getPositionId().getId());
                    ptNames.add(bpt.getPositionId().getPositionName());
                    ogIds.add(bpt.getOrganId().getId());
                    ogNames.add(bpt.getOrganId().getOrganName());
                });
                user.addAttr("ptIds", CollectionUtil.join(ptIds, ","));
                user.addAttr("ptNames", CollectionUtil.join(ptNames, ","));
                user.addAttr("ogIds", CollectionUtil.join(ogIds, ","));
                user.addAttr("ogNames", CollectionUtil.join(ogNames, ","));

                // 获取角色所对应的模块（人员角色，岗位角色，机构角色，兼职角色）
                user.addAttr("modelIds", getModels(user) + ",root");

                // 维护快捷方式
                List<BasicPortal> deletes = DB.list(Select.create(BasicPortal.class).where(
                        Term.eq("userId.id", systemUser.getId()),
                        Term.notIn("modelId.id", user.getAttr("modelIds").toString().split(","))));
                DB.delete(BasicPortal.class, CollectionUtil.joinByFiled(deletes, "id", ",").split(","));
            }

            // 获取系统配置
            BasicConfig config = DB.get(BasicConfig.class, new Term[]{Term.eq("organId.id", user.getAttr("areaId"))});
            if (isAdmin) {
                config = DB.get(BasicConfig.class, new Term[]{Term.eq("isDefault", "1")});
            }

            Map<String, Object> info = ClassUtil.propertySataticClass(ApplicationContext.class);
            info.put("LOCAL_NAME", config.getDemainName());
            info.put("EMAIL_FLAG", config.getEmailFlag());
            info.put("MSG_FLAG", config.getMsgFlag());
            info.put("MAIN_LOGO", config.getMainLogo());
            info.put("IMG_FILE_SIZE", config.getImgFileSize());
            info.put("SYS_NAME", config.getSysName());
            user.builderConfig(info);
            user.addAttr("configId", config.getId());

            if (isAdmin) {
                user.addAttr("isAdmin", true);
            }
        }
        return user;
    }

    /**
     * 获取当前登陆人全部的模块
     *
     * @param user
     * @return
     */
    private String getModels(User user) {
        // 获取人员角色模块
        List<String> uModels = getModelIdsByUser(user.getAttr("userId").toString());

        // 获取人员部门模块
        List<String> oids = new ArrayList<>();
        oids.add(user.getAttr("organId").toString());
        if (!LogicUtil.empty(user.getAttr("ogIds"))) {
            oids.addAll(Arrays.asList(user.getAttr("ogIds").toString().split(",")));
        }
        List<String> oModels = getModelIdsByOgn(oids);

        // 获取人员岗位
        List<String> pids = new ArrayList<>();
        if (user.getAttr("positionId") != null) {
            pids.add(user.getAttr("positionId").toString());
        }
        if (!LogicUtil.empty(user.getAttr("ptIds"))) {
            pids.addAll(Arrays.asList(user.getAttr("ptIds").toString().split(",")));
        }
        List<String> pModels = getModelIdsByPstation(pids);

        // 合并所有模块
        Set<String> models = new HashSet<>();
        models.addAll(uModels);
        models.addAll(oModels);
        models.addAll(pModels);
        return CollectionUtil.join(models, ",");
    }

    /**
     * 根据人员查找出所属模块编号
     *
     * @param uid
     * @return
     */
    private List<String> getModelIdsByUser(String uid) {
        List<BasicRoleUser> basicRoleUsers = DB.list(Select.create(BasicRoleUser.class).fields("roleId.id")
                .where(Term.eq("userId.id", uid)));
        Set<String> ids = new HashSet<>();
        basicRoleUsers.forEach(br -> ids.add(br.getRoleId().getId()));
        return new ArrayList<>(getModelIds(ids));
    }


    /**
     * 获取岗位的角色
     *
     * @param pIds
     * @return
     */
    private List<String> getModelIdsByPstation(List<String> pIds) {
        List<BasicRolePosition> basicRolePstations = DB.list(Select.create(BasicRolePosition.class).fields("roleId.id")
                .where(Term.in("positionId.id", pIds.toArray(new String[pIds.size()]))));
        Set<String> ids = new HashSet<>();
        basicRolePstations.forEach(br -> ids.add(br.getRoleId().getId()));
        return new ArrayList<>(getModelIds(ids));
    }


    /**
     * 根据组织机构查找所属模块
     * <p>
     * 下级组织机构继承上级组织机构的模块
     * </p>
     *
     * @param ognIds
     * @return
     */
    private List<String> getModelIdsByOgn(List<String> ognIds) {
        // 构建出所有的组织机构
        Set<String> ids = new HashSet<>();
        ognIds.forEach(oid -> ids.addAll(getOrganIds(oid, ids)));
        List<BasicRoleOrganization> basicRoleOrganizations = DB.list(Select.create(BasicRoleOrganization.class).fields("roleId.id")
                .where(Term.in("organId.id", ids.toArray(new String[ids.size()]))));
        basicRoleOrganizations.forEach(br -> ids.add(br.getRoleId().getId()));
        return getModelIds(ids);
    }

    /**
     * 根据角色获取模块
     *
     * @param ids
     * @return
     */
    private List<String> getModelIds(Set<String> ids) {
        List<BasicRoleModel> models = DB.list(Select.create(BasicRoleModel.class).fields("modelId.id")
                .where(Term.in("roleId.id", ids.toArray(new String[ids.size()]))));
        List<String> list = new ArrayList<>();
        models.forEach(m -> list.add(m.getModelId().getId()));
        return list;
    }

    /**
     * 获取一个组织机构中所有关联的组织机构编号
     *
     * @param id
     * @param list
     * @return
     */
    private Set<String> getOrganIds(String id, Set<String> list) {
        list.add(id);
        BasicOrganization basicOrganization = DB.get(BasicOrganization.class, id, "organParentId.id");
        list.add(basicOrganization.getId());
        if ("area".equals(basicOrganization.getOrganType())) {
            return list;
        } else {
            return getOrganIds(basicOrganization.getOrganParentId().getId(), list);
        }
    }

}
